package com.gt.utils;

import com.gt.contant.AjaxCode;
import com.gt.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.awt.geom.Point2D;
import java.math.BigDecimal;

/** 距离计算工具类 根据两个不同的经纬度计算他们之间的距离 */
@Slf4j
public class GeoUtils {

    /** 平均半径,单位：m */
    private static final double EARTH_RADIUS = 6371393;

    /**
     * 通过AB点经纬度获取距离
     *
     * @param pointA A点(经，纬)
     * @param pointB B点(经，纬)
     * @return 距离(单位：米)
     */
    public static double getDistance(Point2D pointA, Point2D pointB) {
        // 经纬度（角度）转弧度。弧度用作参数，以调用Math.cos和Math.sin
        // A经弧度
        double radiansAX = Math.toRadians(pointA.getX());
        // A纬弧度
        double radiansAY = Math.toRadians(pointA.getY());
        // B经弧度
        double radiansBX = Math.toRadians(pointB.getX());
        // B纬弧度
        double radiansBY = Math.toRadians(pointB.getY());

        double cos =
                Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX)
                        + Math.sin(radiansAY) * Math.sin(radiansBY);

        // 反余弦值
        double acos = Math.acos(cos);

        // 最终结果
        return new BigDecimal(EARTH_RADIUS * acos / 1000)
                .setScale(2, BigDecimal.ROUND_HALF_DOWN)
                .doubleValue();
    }

    /**
     * 获取用户当前经纬度和商户店铺经纬度之间的距离
     *
     * @param longitude 用户当前地理位置的经度
     * @param latitude 用户当前地理位置的纬度
     * @param merchLongitude 商户店铺地理位置的经度
     * @param merchLatitude 商户店铺地理位置的纬度
     * @return 相隔距离
     */
    public static String getDistance(
            double longitude, double latitude, double merchLongitude, double merchLatitude) {

        if (StringUtils.isBlank(String.valueOf(longitude))) {
           return 0 + "km";
        }
        if (StringUtils.isBlank(String.valueOf(latitude))) {
           return 0 + "km";
        }
        if (StringUtils.isBlank(String.valueOf(merchLongitude))) {
           return 0 + "km";
        }
        if (StringUtils.isBlank(String.valueOf(merchLatitude))) {
           return 0 + "km";
        }

        Point2D pointA = new Point2D.Double(longitude, latitude);
        Point2D pointB = new Point2D.Double(merchLongitude, merchLatitude);
        double distance = getDistance(pointA, pointB);
        if (distance > 99) {
            return "> 99km";
        } else if (distance < 1) {
            return Double.valueOf(distance * 1000).intValue() + "m";
        } else {
            return distance + "km";
        }
    }

    /**
     * 获取用户当前经纬度和商户店铺经纬度之间的距离 - 实际距离，不做转换，单位：km
     *
     * @param longitude 用户当前地理位置的经度
     * @param latitude 用户当前地理位置的纬度
     * @param merchLongitude 商户店铺地理位置的经度
     * @param merchLatitude 商户店铺地理位置的纬度
     * @return 相隔距离
     */
    public static Double getResultDistance(
            double longitude, double latitude, double merchLongitude, double merchLatitude) {

        if (StringUtils.isBlank(String.valueOf(longitude))) {
            return null;
        }
        if (StringUtils.isBlank(String.valueOf(latitude))) {
            return null;
        }
        if (StringUtils.isBlank(String.valueOf(merchLongitude))) {
            return null;
        }
        if (StringUtils.isBlank(String.valueOf(merchLatitude))) {
            return null;
        }

        Point2D pointA = new Point2D.Double(longitude, latitude);
        Point2D pointB = new Point2D.Double(merchLongitude, merchLatitude);
        Double distance = getDistance(pointA, pointB);
        return distance;
    }

    /**
     * wjh
     * 2021/8/31
     * @param shopLongitude 商家经度
     * @param shopLatitude  商家纬度
     * @param userLongitude 用户经度
     * @param userLatitude 用户纬度
     */
    public static String getShopDistance(String shopLongitude,String shopLatitude, String userLongitude,String userLatitude){
        if (StringUtils.isBlank(shopLongitude) || StringUtils.isBlank(shopLatitude)) {
            throw new ServiceException(AjaxCode.DISTANCE_ERROR);
        } else {
            log.info("商户当前地理位置的经纬度 : {} - {}", shopLongitude, shopLatitude);
            log.info("用户当前地理位置的经纬度 : {} - {}", userLongitude, userLatitude);
            // 显示距离
            String distance = GeoUtils.getDistance(Double.parseDouble(userLongitude),
                                                    Double.parseDouble(userLatitude),
                                                    Double.parseDouble(shopLongitude),
                                                    Double.parseDouble(shopLatitude));
            // 实际距离
            /*Double resultDistance = GeoUtils.getResultDistance(Double.parseDouble(userLongitude),
                                            Double.parseDouble(userLatitude),
                                            Double.parseDouble(shopLongitude),
                                            Double.parseDouble(shopLatitude));*/
            return distance;
        }
    }
}
